Skip to main content

Kwikfit MOT Authorisation

Introduction​

Kwikfit generates MOT authorisation request files from their IPP (Invoice Processing Platform) system. These JSON files are imported into ViSN to automatically create walk-in MOT enquiries, attach repair job lines, fetch DVSA MOT history, and progress enquiries through authorisation — eliminating the need for suppliers to manually create and authorise MOT enquiries in ViSN.

Purpose​

To automate the inbound MOT authorisation workflow, Kwikfit exports MOT and repair job lines in a JSON format. ViSN:

  • Validates each row against motAuthorisationSchema
  • Groups valid rows by VRM (REG_NO)
  • Queues one Cloud Task per VRM group
  • Creates or updates an IPP walk-in MOT enquiry
  • Fetches DVSA MOT test history
  • Requests authorisation and runs auto-authorisation against lease rules

Process flow​

File format​

JSON format — *.json

The file must be a top-level JSON array. Each element is a flat object representing one job line.

Grouping rules​

Rows are grouped by REG_NO (VRM) during import:

  1. Each row is validated individually against motAuthorisationSchema.
  2. Valid rows with the same REG_NO are grouped into one enquiry payload.
  3. Each group must contain exactly one MOTPASS row (the MOT job line). Groups without a MOTPASS row are skipped and logged as "The MOT line was not found."
  4. All MOTADD rows in the group are attached as repair parts on the same enquiry.

AUTH_NO values​

ValueMeaningViSN mapping
MOTPASSMOT test lineCreates MOT job line (CLASS_4) with cost from PART_NET
MOTADDRepair / parts lineCreates repair job line with parts mapped from VISN_CODE, QUANTITY, and PART_NET

Fields​

ColumnFieldTypeLengthCommentMandatoryExample
AACCOUNT_NOText6Kwikfit account number for the lease company. Must match ippMappingAccountId in ancillary/config/kwikFitAccountMapping.YesN3301T
BTRAN_DATEDate10DD/MM/YYYY — transaction date. Included in enquiry notes.Yes19/11/2025
CAUTH_NOText20Must be MOTPASS (MOT line) or MOTADD (repair line).YesMOTPASS
DTRAN_NOText100Kwikfit transaction number. Stored as enquiryExternalRef on the enquiry. Alphanumeric.Yes32619112447
EREG_NOText20Vehicle Registration Mark (VRM). Used to group rows and match stock. Validated against VRM regex.YesEJ70UJF
FMILEAGENumber8Vehicle mileage. Integer, max 8 digits. Applied to the enquiry bid on authorisation.Yes49090
GKF_CENTRENumber8Kwikfit centre ID. Must match a service unit ippSupplierId in ViSN.Yes326
HPARD_IDText16Kwikfit part identifier. Validated on import; repair parts are mapped via VISN_CODE.YesMOT
IQUANTITYNumber(9,2)12Part quantity. For MOTPASS must be exactly 1. For MOTADD must be numeric in nnnnnn.nn format.Yes1
JPART_NETNumber(9,2)12Net part price. For MOT lines this is the MOT cost. Format: nnnnnn.nnYes40.00
KVISN_CODEText20ViSN part code. Required for MOTADD rows (maps to partNumber). Not required for MOTPASS rows.ConditionalKF

Example file structure​

Each VRM group requires one MOTPASS row plus zero or more MOTADD rows:

[
{
"ACCOUNT_NO": "N3301T",
"TRAN_DATE": "19/11/2025",
"AUTH_NO": "MOTPASS",
"TRAN_NO": "32619112447",
"REG_NO": "EJ70UJF",
"MILEAGE": 49090,
"KF_CENTRE": 326,
"PARD_ID": "MOT",
"QUANTITY": 1,
"PART_NET": 54.85
},
{
"ACCOUNT_NO": "N3301T",
"TRAN_DATE": "19/11/2025",
"AUTH_NO": "MOTADD",
"TRAN_NO": "32619112447",
"REG_NO": "EJ70UJF",
"MILEAGE": 49090,
"KF_CENTRE": 326,
"PARD_ID": "A827SWIP",
"QUANTITY": 1,
"PART_NET": 38.6,
"VISN_CODE": "KF"
}
]

Import Manager​

Endpoint​

POST /kwikfit-mot-authorisation-import

File upload and processing​

  1. File location: The import file is uploaded to Google Cloud Storage in the designated import drop path.
  2. Import trigger: Cloud Scheduler provides the account ID and file location to Import Manager. The request payload:
FieldDescription
bucketGCS bucket name
importFileDropPathPath where the file is located in the bucket
importFileNameName of the JSON file to import
appDirectoryLocal directory path for temporary file storage
accountIdSupplier group account ID in ViSN
persistWhen true, valid VRM groups are queued as Cloud Tasks; when false, validation only
importPathArchive path used after successful import
delayPerRecordDelay in seconds between queued tasks (default: 1)
fatalErrorEmailToAddressEmail address for fatal error notifications

Example payload:

{
"bucket": "import-bucket-name",
"importFileDropPath": "kwikfit-mot/",
"importFileName": "mot_authorisation_20251119.json",
"appDirectory": "/tmp/imports/",
"accountId": "RMZj6hYyP4PqhobUm1zw",
"persist": true,
"importPath": "archive/kwikfit-mot/",
"delayPerRecord": 1,
"fatalErrorEmailToAddress": "admin@example.com"
}

Data validation​

  1. JSON parsing: The file is streamed and parsed as a top-level JSON array. Invalid JSON format aborts the import.
  2. Schema validation: Each row is validated against motAuthorisationSchema (see Fields).
  3. Grouping: Valid rows are grouped by REG_NO.
  4. Enquiry object build: For each group, a MOTPASS row is required. The importer builds an enquiry payload:
    • source: IPP
    • vrm: from REG_NO
    • customerAccountNumber: from ACCOUNT_NO
    • assignSite: from KF_CENTRE
    • mileage: from MILEAGE
    • enquiryExternalRef: from TRAN_NO
    • enquiryNotes: Transaction Number: {TRAN_NO}, Date: {TRAN_DATE}
    • jobLines: MOT line from MOTPASS + repair line(s) from MOTADD rows
  5. Queueing: When persist is true, each valid group is written to the ancillary Cloud Task queue with type FOR_MOT_AUTHORISATION.

Processing statistics​

StatisticDescription
motEnquiriesAddedToQueueVRM groups successfully queued
motEnquiriesFailedValidationRows that failed schema validation
motEnquiriesSkippedNoMotJobLineGroups with no MOTPASS row
motEnquiriesGeneratedEnquiries created (incremented by Queue Services)
motEnquiriesGenerationFailedEnquiries that failed during processing
enquiriesUpdatedWithMotDetailsExisting enquiries updated with MOT/DVSA details

Cloud Task processing​

Overview​

Queue configuration​

  • Queue Name: ipp-mot-authorisation
  • Target URL: Queue Services endpoint /mot-authorisation
  • Task Type: FOR_MOT_AUTHORISATION

Cloud Task payload​

Each task contains:

{
"rowNumber": 1,
"accountId": "RMZj6hYyP4PqhobUm1zw",
"triggeredOn": "2025-11-19",
"motEnquiry": {
"source": "IPP",
"vrm": "EJ70UJF",
"customerAccountNumber": "N3301T",
"assignSite": 326,
"mileage": 49090,
"enquiryExternalRef": "32619112447",
"enquiryNotes": "Transaction Number: 32619112447, Date: 19/11/2025",
"jobLines": [
{
"jobLineType": "MOT",
"motClass": "CLASS_4",
"cost": 54.85
},
{
"jobLineType": "REPAIR",
"repairId": "999990",
"parts": [
{
"partNumber": "KF",
"quantity": 1,
"unitPrice": 38.6
}
]
}
]
}
}

Precondition checks​

Before creating or updating an enquiry, Queue Services runs the following checks:

CheckDescriptionAbort reason
Service unit lookupFinds service unit in account where ippSupplierId = KF_CENTREKF_CENTRE: {value} is not found
Service unit statusService unit must be liveService Unit for KF_CENTRE: {value} is not live
Lease mappingResolves lease company from ancillary/config/kwikFitAccountMapping where ippMappingAccountId = ACCOUNT_NONo Lease Company found for ACCOUNT_NO: {value}
Stock lookupFinds active stock for REG_NO under the resolved leaseNo stock item found for REG_NO: {value}
Contract statusStock must not be terminatedStock item for REG_NO: {value} is not active

Enquiry creation and update​

New enquiry​

When no reusable enquiry exists for the VRM at the same service unit, Queue Services calls Callable Service:

POST /api/v1/enquiry/createIPPEnquiry

This creates a walk-in MOT enquiry with:

  • enquirySource: Walk-in
  • enquiryStatus: Check-in Complete
  • serviceType: MOT
  • MOT and repair job lines from the import payload
  • enquiryExternalRef from TRAN_NO

Existing enquiry reuse​

Queue Services searches for the latest non-terminal enquiry for the same VRM, account, and service unit. Reusable statuses:

  • New
  • Bid Accepted
  • Checked In
  • Check-in Complete
  • Checked In By Driver

Excluded statuses (new enquiry created instead): Cancelled, Declined to Bid, Completed, Invoiced, Deleted.

DVSA MOT details​

After enquiry creation or update, Queue Services fetches DVSA MOT test history for the VRM:

  1. Calls the DVSA MOT API via fetchDvsaMotDetails
  2. Processes and saves MOT details to the enquiry when tests are returned
  3. If DVSA returns no tests, processing continues (event log: "DVSA did not return MOT information for this vehicle")
  4. If DVSA fetch fails with an error, the row is aborted

Authorisation​

Once preconditions pass and the enquiry is ready:

  1. Queue Services calls POST /api/v1/enquiry/requestAuthorisation with:
    • authorisationStatus: REQUESTED
    • authorisationLastRequestedBy: { firstname: "IPP", lastname: "", company: supplierName }
    • Bid data including mileage from the import file
  2. Callable Service sets authorisation status to Requested and runs auto-authorisation against the lease company's auto-authorisation configuration.
  3. If auto-authorisation is not enabled for the lease, processing aborts with: "Auto authorisation is not enabled for {lease name}".
  4. If bid warnings exist after the authorisation request, processing aborts with the warning messages.
  5. On success, the enquiry reaches Authorised or Partially Authorised status.

API reference​

Import Manager​

MethodEndpointDescription
POST/kwikfit-mot-authorisation-importDownload, validate, group, and queue MOT authorisation file

Queue Services​

MethodEndpointDescription
POST/mot-authorisationProcess a single MOT authorisation Cloud Task

Callable Service​

MethodEndpointDescription
POST/api/v1/enquiry/createIPPEnquiryCreate new IPP walk-in MOT enquiry
POST/api/v1/enquiry/addIPPJobLinesToExistingEnquiryAppend MOT/repair lines to existing enquiry
POST/api/v1/enquiry/checkExistingEnquiryForMotAuthorisationLook up reusable enquiry for VRM (used internally)
POST/api/v1/enquiry/requestAuthorisationRequest authorisation and trigger auto-authorisation

Logging and reporting​

Error scenarios​

ScenarioResultLogged reason
Schema validation failureSkippedField-specific validation errors
No MOTPASS row in VRM groupSkippedThe MOT line was not found.
Service unit not foundAbortedKF_CENTRE: {value} is not found
Service unit not liveAbortedService Unit for KF_CENTRE: {value} is not live
Lease mapping missingAbortedNo Lease Company found for ACCOUNT_NO: {value}
Stock not foundAbortedNo stock item found for REG_NO: {value}
Stock terminatedAbortedStock item for REG_NO: {value} is not active
Existing enquiry in authorisationSkippedExisting enquiry is in Authorisation status...
DVSA fetch errorAbortedDVSA error message
Auto-authorisation disabledAbortedAuto authorisation is not enabled for {lease}
Bid warningsAbortedWarning messages from bid validation

Import and processing logs​

Import Manager and Queue Services both write to the same ancillary log collection:

  • Location: ancillary/logs/motAuthorisation/{accountId}/{year}/{month}/{date}/logs
  • Import Manager logs per-row validation and queueing (CSV format)
  • Queue Services logs enquiry creation, DVSA fetch, and authorisation steps
  • End-of-log entry with aggregated statistics and counters: motEnquiriesGenerated, motEnquiriesGenerationFailed, enquiriesUpdatedWithMotDetails

Log CSV export​

A scheduled function (generateMotAuthorisationLogsCSV) generates CSV exports of the import logs:

  • Trigger: Pub/Sub topic generateMotAuthorisationLogsCSV
  • Function: generateMotAuthorisationLogsCSV
  • Default: Exports today's logs (configurable via dateTimeStamp in message)
  • Output location: {logPath}{year}/{monthName}/{day}/mot_authorisation_logs_{year}-{month}-{day}.csv
  • Process log type: KWIKFIT_MOT_AUTHORISATION_IMPORT

A Scheduler should be created in Cloud Scheduler with the following parameters:

  • Name: Generate MOT authorisation logs CSV
  • Region: europe-west2
  • Frequency: Daily (recommended: 0 23 * * * — runs at 11 PM daily)
  • TimeZone: GMT London
  • Topic: projects/[PROJECT_ID]/topics/generateMotAuthorisationLogsCSV
  • Message body: a JSON object including the following parameters:

    • accountId: Supplier group account ID (required)
    • logPath: GCS export path prefix (required)
    • archivePath: GCS archive path prefix (required)
    • archiveBucket: GCS bucket for archiving existing exports (optional)
    • sendReportTo: Comma-separated email list for CSV report delivery (optional)
    • dateTimeStamp: in format yyyy-MMM-dd e.g. 2025-Nov-19; defaults to today when omitted

Admin UI monitoring​

  • Process logs visible in Admin UI under Process Logs
  • Process log type: KWIKFIT_MOT_AUTHORISATION_IMPORT
  • Displays import statistics when successful

Setup required​

Lease account mapping​

Each Kwikfit ACCOUNT_NO must exist in Firestore:

  • Path: ancillary/config/kwikFitAccountMapping
  • Field: ippMappingAccountId → matches ACCOUNT_NO from the import file
  • Field: leaseCompanyId → target lease company in ViSN

Service unit mapping​

Each Kwikfit centre (KF_CENTRE) must map to a service unit in the supplier account:

  • Field: ippSupplierId on the service unit → matches KF_CENTRE from the import file
  • Service unit unitStatus.status must be live

Auto-authorisation​

Auto-authorisation must be enabled on the lease company configuration for authorisation to complete automatically.


Authored By: Vishwa Kumar on Jul 2, 2026